package com.smartian.v2.impl;

import android.text.TextUtils;

import com.smartian.v2.AbstractTextParser;
import com.smartian.v2.OpLog;
import com.smartian.v2.TextPattern;
import com.smartian.v2.filters.TextParserInterceptorManager;
import com.smartian.v2.model.DateTimeNode;
import com.smartian.v2.model.ScheduleTaskBean;
import com.smartian.v2.utils.DateTimeHelper;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Created by tianweitong on 2020/3/13.
 */

public class MonthlyTextParser extends AbstractTextParser {
    private int mFrequent = 1;
    private List<DateTimeNode> mDateTimeNodeList = new ArrayList<>();
    private volatile boolean mHasParsed = false;

    public MonthlyTextParser(String sourceText, String repeatText, int repeatTextIndex) {
        super(sourceText, repeatText, repeatTextIndex);
    }

    @Override
    public ScheduleTaskBean getScheduleTaskBean() {
        startHandler();
        OpLog.d("TextParser",mDateTimeNodeList+" , "+mFrequent+" "+getRepeatText());
        if(mDateTimeNodeList!=null) {
            Collections.sort(mDateTimeNodeList);
        }
        DateTimeNode dateNode = DateTimeHelper.findBestDateNode(mDateTimeNodeList,DateTimeNode.TYPE_DATE);
        DateTimeNode timeNode = DateTimeHelper.findBestDateNode(mDateTimeNodeList,DateTimeNode.TYPE_TIME);

        if(dateNode==null || timeNode==null){
            return null;
        }
        if(TextUtils.isEmpty(dateNode.resultText) || TextUtils.isEmpty(timeNode.resultText)){
            return null;
        }

        List<DateTimeNode> dateTimeNodes  = new ArrayList<>();

        dateTimeNodes.add(dateNode);
        dateTimeNodes.add(timeNode);

        String date = dateNode.resultText;
        String time = timeNode.resultText;
        String dateTime = DateTimeHelper.formatMonthTime(date,time);
        if(TextUtils.isEmpty(dateTime)) return null;

        ScheduleTaskBean scheduleTaskBean = new ScheduleTaskBean();
        scheduleTaskBean.setFraquent(mFrequent);
        scheduleTaskBean.setRepeatText(getRepeatText());
        scheduleTaskBean.setRepeatType(TextPattern.REPEAT_MONTHLY);
        scheduleTaskBean.setDateTime(dateTime);
        scheduleTaskBean.setDateTimeFormat(getDateTimeFormat());
        scheduleTaskBean.setSourceText(getSourceText());
        scheduleTaskBean.setDateTimeNodes(dateTimeNodes);

        return scheduleTaskBean;
    }

    private void startHandler() {
        if(!mHasParsed) {
            List<DateTimeNode> dateTimeNodes = startParse();
            if (dateTimeNodes != null) {
                mDateTimeNodeList.clear();
                dateTimeNodes = TextParserInterceptorManager.dispatchIntercept(this,TextPattern.REPEAT_MONTHLY,dateTimeNodes);
                mDateTimeNodeList.addAll(dateTimeNodes);
            }
            mHasParsed = true;
        }
    }

    private List<DateTimeNode> startParse() {

        List<DateTimeNode> dateTimeNodes = new ArrayList<>();
        String sourceText = getSourceText();
        if(TextUtils.isEmpty(sourceText)) return dateTimeNodes;
        mFrequent = parseFrequent();
        if(mFrequent<0) return dateTimeNodes;

        List<DateTimeNode> dateNodes = getParseDate();
        List<DateTimeNode> timeNodes = getParseTime();

        if(dateNodes.size()==0){
            int day = Calendar.getInstance().get(Calendar.DAY_OF_MONTH);

            DateTimeNode timeNode = new DateTimeNode();
            timeNode.text = "";
            timeNode.index = 0;
            timeNode.resultText = String.format("%s",day);
            timeNode.locatorText = "";
            timeNode.type = DateTimeNode.TYPE_DATE;
            dateNodes.add(timeNode);
        }
        if(timeNodes.size()==0) {
            String currentTime = DateTimeHelper.getCurrentTime();
            DateTimeNode dateTimeNode = new DateTimeNode();
            dateTimeNode.text = "";
            dateTimeNode.index = 0;
            dateTimeNode.resultText = currentTime;
            dateTimeNode.locatorText = "";
            dateTimeNode.type = DateTimeNode.TYPE_TIME;
            timeNodes.add(dateTimeNode);
        }
        if(dateNodes!=null) {
            dateTimeNodes.addAll(dateNodes);
        }
        if(timeNodes!=null) {
            dateTimeNodes.addAll(timeNodes);
        }
        return dateTimeNodes;

    }

    @Override
    public List<DateTimeNode> getParseDate() {
        List<DateTimeNode> dtns = new ArrayList<>();
        String pattern = getRepeatText() + "\\w{1,3}(日|号)?";
        String sourceText = getSourceText();
        Matcher matcher = Pattern.compile(pattern).matcher(sourceText);

        while (matcher.find()){
            String group = matcher.group();
            String[] parts = group.split(TextPattern.WORD_MONTH);

            if(parts==null || parts.length<2){
                continue;
            }
            String  dayPart = parts[1];

            if(TextUtils.isEmpty(group)) continue;
            String number = DateTimeHelper.readFirstNumber(dayPart);
            if(TextUtils.isEmpty(number) || !TextUtils.isDigitsOnly(number)) continue;

            int integerValue = DateTimeHelper.getIntegerValue(number);
            if(integerValue>31 || integerValue<=0) continue;

            int length = String.valueOf(integerValue).length();
            if(dayPart.length()>length){
                char ch = dayPart.charAt(length);
                String chWord = String.valueOf(ch);

                if(!TextPattern.WORD_DAY.equals(chWord) && !TextPattern.WORD_DAY_ALIAS.equals(chWord)){
                    dayPart = String.valueOf(integerValue);
                }
            }

            DateTimeNode dateTimeNode = new DateTimeNode();
            String resultText = String.format("%s",integerValue);
            dateTimeNode.text = dayPart;
            dateTimeNode.index = matcher.start();
            dateTimeNode.resultText = resultText;

            dtns.add(dateTimeNode);

            break;

        }
        return dtns;
    }

    @Override
    public int parseFrequent() {
        String repeatText = getRepeatText();
        if(TextUtils.isEmpty(repeatText)) return -1;

        if(repeatText.contains(TextPattern.WORD_6_MONTH_IN_YEAR_ALIAS)){
            return 6;
        }
        if(repeatText.contains(TextPattern.WORD_3_MONTH_IN_YEAR_ALIAS)){
            return 3;
        }
        return super.parseFrequent();
    }

    @Override
    public boolean isValid() {
        startHandler();
        return mFrequent>0;
    }
    @Override
    public String getDateTimeFormat() {
        return "dd HH:mm";
    }
}
